package com.laiketui.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.laiketui.common.api.PublicMemberService;
import com.laiketui.common.api.PubliceService;
import com.laiketui.common.mapper.*;
import com.laiketui.core.cache.RedisUtil;
import com.laiketui.core.common.SplitUtils;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.core.lktconst.GloabConst;
import com.laiketui.core.utils.help.SpringHelper;
import com.laiketui.domain.config.ConfiGureModel;
import com.laiketui.domain.lktconst.ErrorCode;
import com.laiketui.domain.mch.CartModel;
import com.laiketui.domain.mch.MchModel;
import com.laiketui.domain.mch.RoleModel;
import com.laiketui.domain.product.BrandClassModel;
import com.laiketui.domain.product.ProductListModel;
import com.laiketui.domain.user.User;
import com.laiketui.domain.user.UserAddress;
import com.laiketui.order.OrderParentNoSeq;
import com.laiketui.order.api.dto.*;
import com.laiketui.order.api.enums.*;
import com.laiketui.order.api.params.*;
import com.laiketui.order.domain.Order;
import com.laiketui.order.domain.OrderDetail;
import com.laiketui.order.domain.OrderParent;
import com.laiketui.order.domain.OrderParentMessage;
import com.laiketui.order.entity.OrderCombiner;
import com.laiketui.order.mapper.OrderParentMapper;
import com.laiketui.order.mapstruct.*;
import com.laiketui.order.runner.OrderCancelRunner;
import com.laiketui.order.service.*;
import com.laiketui.order.utils.PriceUtil;
import com.wechat.pay.java.service.brandprofitsharing.BrandProfitSharingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiangxiang
 * @description 针对表【lk_order_parent】的数据库操作Service实现
 * @createDate 2024-08-13 22:47:12
 */
@Service
@Slf4j
public class OrderParentServiceImpl extends ServiceImpl<OrderParentMapper, OrderParent>
        implements OrderParentService {
    //税费扣8个点
//    private static final long taxRate = 8L;


    @Autowired
    private ProductListModelMapper productListModelMapper;

    @Autowired
    private MchModelMapper mchModelMapper;
    @Autowired
    private ConfiGureModelMapper configureModelMapper;

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private PublicMemberService publicMemberService;
    @Autowired
    private CartModelMapper cartModelMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private BalanceRecordService balanceRecordService;

    @Autowired
    private OrderParentMessageService orderParentMessageService;
    @Autowired
    private BrandClassModelMapper brandClassModelMapper;
    @Autowired
    RoleModelMapper roleMapper;
    @Autowired
    private PubliceService publiceService;
    @Autowired
    private OrderParentNoSeq orderParentNoSeq;

    @Override
    public OrderParentDTO orderDetail(OrderInfoParams orderInfoParams, User user) {

        OrderParent orderParent = getOrderParent(orderInfoParams.getOrderParentNo());
        OrderParentDTO orderParentDTO = OrderParentMapstructMapper.INSTANCE.toDTO(orderParent);
        log.info("获取母单成功");
        List<Order> orders= orderService.findByOrderParentNo(orderParent.getOrderParentNo());
        List<OrderDTO> orderDTOList = OrderMapstructMapper.INSTANCE.toDTOs(orders);
        log.info("获取子单成功");
        List<OrderDetail> orderDetails=orderDetailService.findByOrderParentNo(orderParent.getOrderParentNo());
        List<OrderDetailDTO> detailsList = OrderDetailMapstructMapper.INSTANCE.toDTOs(orderDetails);
        log.info("获取订单子项成功");

        List<OrderParentMessage> messages=orderParentMessageService.findByOrderParentNo(orderParent.getOrderParentNo());
        List<OrderParentMessageDTO> messageDTOList = OrderParentMessageMapstructMapper.INSTANCE.toDTOs(messages);
        log.info("获取订单信息成功");
        orderParentDTO.setMessages(messageDTOList);
        Map<Integer, List<OrderDetailDTO>> detailMap = detailsList.stream().collect(Collectors.groupingBy(OrderDetailDTO::getMchId));
        orderDTOList.forEach(orderDTO -> {
            orderDTO.setDetails(detailMap.get(orderDTO.getMchId()));
        });
        orderParentDTO.setOrders(orderDTOList);
        return orderParentDTO;
    }

    @Override
    public boolean updateStatusCancel(String orderParentNo,String cancelReason) {
        log.info("开始取消母单:{}",orderParentNo);
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderParent::getOrderParentNo, orderParentNo);
        wrapper.eq(OrderParent::getStatus, OrderParentStatusEnum.WAIT_PAY.getCode());
        OrderParent orderParent = new OrderParent();
        orderParent.setUpdateBy("系统取消订单");
        orderParent.setUpdateTime(new Date());
        orderParent.setStatus(OrderParentStatusEnum.CANCEL.getCode());
        orderParent.setCancelReason(cancelReason);
        boolean update = update(orderParent, wrapper);
        log.info("取消母单:{}",update);
        return update;
    }

    @Override
    public Page<OrderParentDTO> orderList(OrderParentListParams params, User user) {
        params.setUserId(user.getUser_id());
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(OrderParent::getId);
        Page<OrderParentDTO> page = pageList(wrapper,params);
        page.getRecords().forEach(orderParentDTO -> {
            String orderParentNo;
            orderParentNo = orderParentDTO.getOrderParentNo();
            orderParentDTO.setSettlementAmount(BigDecimal.ZERO);
            orderParentDTO.setTotalCostPrice(BigDecimal.ZERO);
            List<OrderProductsDTO> products = getOrderProductsByOrderParentNo(orderParentNo);
            orderParentDTO.setProducts(products);
        });

        return page;
    }

    private @NotNull Page<OrderParentDTO> pageList(LambdaQueryWrapper<OrderParent> wrapper,OrderParentListParams params) {
        int pageSize = params.getPageSize();
        int current = params.getPageNum();


        wrapper.eq(OrderParent::getDeleted, DelFlagEnum.NORMAL.getCode())
                .eq(OrderParent::getStoreId, params.getStoreId())
                .orderByDesc(OrderParent::getCreateTime);
        if (StringUtils.isNotBlank(params.getUserId())) {
            wrapper.eq(OrderParent::getUserId, params.getUserId());
        }
        if (Objects.nonNull(params.getStatus())) {
            wrapper.eq(OrderParent::getStatus, params.getStatus());
        }
        if (Objects.nonNull(params.getOrderType())) {
            wrapper.eq(OrderParent::getOrderType, params.getOrderType());
        }
        if(StringUtils.isNotBlank(params.getOrderParentNo())){
            wrapper.eq(OrderParent::getOrderParentNo,params.getOrderParentNo());
        }
        if(Objects.nonNull(params.getDeliveryCategory()) && DeliveryCategoryEnum.DELIVERY_CATEGORY_1.getCode().equals(params.getDeliveryCategory())){
            Calendar calendar = Calendar.getInstance();
            setDayStartTime(calendar);
            wrapper.le(OrderParent::getRealDeliveryTime, calendar.getTime());
        }else if(Objects.nonNull(params.getDeliveryCategory()) && DeliveryCategoryEnum.DELIVERY_CATEGORY_2.getCode().equals(params.getDeliveryCategory())){
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH, 15);
            setDayStartTime(calendar);
            wrapper.le(OrderParent::getRealDeliveryTime, calendar.getTime());
        }else if(Objects.nonNull(params.getDeliveryCategory()) && DeliveryCategoryEnum.DELIVERY_CATEGORY_3.getCode().equals(params.getDeliveryCategory())){
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH, 7);
            setDayStartTime(calendar);
            wrapper.le(OrderParent::getRealDeliveryTime, calendar.getTime());
        }
        if(Objects.nonNull(params.getStartTime())){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(params.getStartTime());
            setDayStartTime(calendar);
            wrapper.ge(OrderParent::getCreateTime, calendar.getTime());
        }
        if(Objects.nonNull(params.getEndTime())){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(params.getEndTime());
            setDayStartTime(calendar);
            wrapper.le(OrderParent::getCreateTime, calendar.getTime());
        }
        if(StringUtils.isNotBlank(params.getKeyWords())){
            wrapper.like(OrderParent::getKeyWords, params.getKeyWords());
        }

        Page<OrderParent> selectPage = new Page<>();
        selectPage.setCurrent(current);
        selectPage.setSize(pageSize);
        IPage<OrderParent> retPage = page(selectPage, wrapper);
        List<OrderParent> records = retPage.getRecords();
        List<OrderParentDTO> retDtos = OrderParentMapstructMapper.INSTANCE.toDTOs(records);

        Page page = new Page();
        page.setTotal(retPage.getTotal());
        page.setRecords(retDtos);
        page.setSize(retPage.getSize());
        page.setCurrent(retPage.getCurrent());
        page.setPages(retPage.getPages());
        return page;
    }

    private static void setDayStartTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    @Override
    public ConfirmOrderParentDTO confirmOrder(ConfirmOrderParams confirmOrderParams, User user) {
        try {
            if (StringUtils.isBlank(confirmOrderParams.getCartIds())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到购物车信息", "confirmOrder");
            }
            List<CartModel> allCartModels = getCartModels(confirmOrderParams.getCartIds());
            if (CollectionUtils.isEmpty(allCartModels)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到购物车信息", "confirmOrder");
            }
            //获取未下架的商品和未下架的sku列表
            List<ProductListModel> productListModelsByCarts = getProductListModelsByCarts(allCartModels);
            if (CollectionUtils.isEmpty(productListModelsByCarts)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到商品信息", "confirmOrder");
            }
            List<CartModel> cartModels = new LinkedList<>(allCartModels);
            List<Integer> offlineProductIds = new ArrayList<>(productListModelsByCarts.size());
            for (ProductListModel productListModel : productListModelsByCarts) {
                if ("3".equals(productListModel.getStatus())) {
                    offlineProductIds.add(productListModel.getId());
                }
            }
            //删除已下架商品
            List<Integer> needDelCartIds = new ArrayList<>();
            Iterator<CartModel> iterator = cartModels.iterator();
            if (!CollectionUtils.isEmpty(offlineProductIds)) {
                while (iterator.hasNext()) {
                    CartModel cartModel = iterator.next();
                    if (offlineProductIds.contains(cartModel.getGoods_id())) {
                        needDelCartIds.add(cartModel.getId());
                        iterator.remove();
                    }
                }
            }

            if (CollectionUtils.isEmpty(cartModels)) {
                delCarts(needDelCartIds, user.getUser_id(), confirmOrderParams.getStoreId());
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到商品信息", "confirmOrder");
            }

            List<ConfiGureModel> skuList = getSkuList(cartModels);
            if (CollectionUtils.isEmpty(skuList)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到商品sku信息", "confirmOrder");
            }

            //删除已下架的sku
            List<String> offLineSkuIds = new ArrayList<>(skuList.size());
            for (ConfiGureModel confiGureModel : skuList) {
                if ("3".equals(confiGureModel.getStatus())) {
                    offLineSkuIds.add(String.valueOf(confiGureModel.getId()));
                }
            }
            iterator = cartModels.iterator();
            if (!CollectionUtils.isEmpty(offLineSkuIds)) {
                while (iterator.hasNext()) {
                    CartModel cartModel = iterator.next();
                    if (offLineSkuIds.contains(cartModel.getSize_id())) {
                        needDelCartIds.add(cartModel.getId());
                        iterator.remove();
                    }
                }
            }
            if (CollectionUtils.isEmpty(cartModels)) {
                delCarts(needDelCartIds, user.getUser_id(), confirmOrderParams.getStoreId());
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "未查询到商品信息", "confirmOrder");
            }

            //获取商品列表
            List<ProductListModel> productModelLists = getProductListModelsByCarts(cartModels);
            user= getUser(user.getStore_id(),user.getUser_id());
            //生成母单/子单/订单子项数据
            UserPlaceOrderParams params = new UserPlaceOrderParams();
            params.setUser(user);
            params.setOrderType(OrderTypeEnum.SELF.getCode());
            params.setOperationType(OrderOperationTypeEnum.USER.getCode());
            String discount = publicMemberService.getMemberDiscountByToken(confirmOrderParams.getAccessId(), confirmOrderParams.getStoreId());
            params.setRate(new BigDecimal(discount));
            params.setStoreId(confirmOrderParams.getStoreId());
            params.setInvoice(OrderInvoiceEnum.YES.getCode());
            params.setCartModels(cartModels);
            OrderCombiner orderCombiner = getOrderCombiner(params, productModelLists);
            if (CollectionUtils.isEmpty(orderCombiner.getOrders())
                    || CollectionUtils.isEmpty(orderCombiner.getDetails())
                    || Objects.isNull(orderCombiner.getOrderParent())
            ) {
                throw new RuntimeException("获取确认订单失败");
            }
            Map<Integer, MchModel> mchModelMap = getMchModelMap(productModelLists);
            OrderParent orderParent = orderCombiner.getOrderParent();
            ConfirmOrderParentDTO confirmOrderParentDTO = new ConfirmOrderParentDTO();
            confirmOrderParentDTO.setOrders(getConfirmOrders(orderCombiner.getOrders(), orderCombiner.getDetails(), mchModelMap));
            confirmOrderParentDTO.setTaxation(PriceUtil.longToBigDecimalPrice(orderParent.getTaxation()));
            confirmOrderParentDTO.setTotalPrice(PriceUtil.longToBigDecimalPrice(orderParent.getTotalPrice()));
            confirmOrderParentDTO.setTotalVolume(orderParent.getTotalVolume());
            confirmOrderParentDTO.setCartIds(confirmOrderParams.getCartIds());
            confirmOrderParentDTO.setOldTotalPrice(PriceUtil.longToBigDecimalPrice(orderCombiner.getOrderParent().getOldTotalPrice()));
            return confirmOrderParentDTO;
        } catch (LaiKeAPIException e) {
            log.error("获取确认订单失败 异常", e);
            throw e;
        } catch (Exception e) {
            log.error("获取确认订单失败 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_HQDDQRXXSB, "获取确认订单失败", "confirmOrder");
        }

    }

    private User getUser(Integer storeId, String userId) {
        User user = new User();
        user.setUser_id(userId);
        user.setStore_id(storeId);
        return userMapper.selectOne(user);
    }

    @Override
    public PlaceOrderResultDTO orderInfo(OrderInfoParams orderInfoParams, User user) {
        User selectUser = new User();
        selectUser.setStore_id(user.getStore_id());
        selectUser.setUser_id(user.getUser_id());
        user = userMapper.selectOne(selectUser);


        OrderParent orderParent = getOrderParent(orderInfoParams.getOrderParentNo());

        Long deductionAmount;
        long userHadMoney = Objects.nonNull(user.getBalance()) ? user.getBalance() : 0L;
        if (userHadMoney > (orderParent.getPayPrice())) {
            //如果余额足够支付
            deductionAmount = orderParent.getPayPrice();
        } else {
            //如果不够支付
            deductionAmount = Objects.nonNull(user.getBalance()) ? user.getBalance() : 0L;
        }
        orderParent.setDeductionAmount(deductionAmount);
        orderParent.setOfflinePayStatus(OrderOfflinePayStatusEnum.WAIT_PAY.getCode());
        long offlinePayAmount= orderParent.getPayPrice() - deductionAmount;
        orderParent.setOfflinePayAmount(Math.max(offlinePayAmount, 0L));


        OrderParentDTO orderParentDTO = OrderParentMapstructMapper.INSTANCE.toDTO(orderParent);
        PlaceOrderResultDTO placeOrderResultDTO = new PlaceOrderResultDTO();
        placeOrderResultDTO.setOfflinePayAmount(orderParentDTO.getOfflinePayAmount());
        placeOrderResultDTO.setInvoice(orderParentDTO.getInvoice());
        placeOrderResultDTO.setOrderParentNo(orderParentDTO.getOrderParentNo());
        placeOrderResultDTO.setExpireTime(orderParentDTO.getExpireTime());


        placeOrderResultDTO.setExpireTimeSeconds(getTimeSeconds(orderParentDTO.getExpireTime()));
        placeOrderResultDTO.setBalance(PriceUtil.longToBigDecimalPrice(user.getBalance()));
        placeOrderResultDTO.setFreezeBalance(PriceUtil.longToBigDecimalPrice(user.getFreezeBalance()));
        placeOrderResultDTO.setOrderType(orderParentDTO.getOrderType());
        placeOrderResultDTO.setDeductionAmount(orderParentDTO.getDeductionAmount());
        placeOrderResultDTO.setPayPrice(orderParentDTO.getPayPrice());
        return placeOrderResultDTO;
    }


    public OrderParent getOrderParent(String orderParentNo) {
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderParent::getOrderParentNo, orderParentNo);
        return getOne(wrapper);
    }

    @Override
    public List<OrderParent> getByOrerParentNoList(List<String> orderParentNos) {
        if(CollectionUtils.isEmpty(orderParentNos)){
            return  new ArrayList<>();
        }
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderParent::getOrderParentNo, orderParentNos);
        return list(wrapper);
    }

    @Override
    public boolean updateByOrderParentNo(String orderParentNo, OrderParent orderParent) {
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
        return update(orderParent, wrapper.eq(OrderParent::getOrderParentNo, orderParentNo));
    }


    public List<ConfirmOrderDTO> getConfirmOrders(List<Order> orders, List<OrderDetail> details, Map<Integer, MchModel> mchModelMap) {
        List<ConfirmOrderDTO> confirmOrders = new ArrayList<>(orders.size());
        List<ConfirmOrderDetailDTO> confirmOrderDTOs = new ArrayList<>(details.size());
        details.forEach(orderDetail -> {
            ConfirmOrderDetailDTO confirmOrderDetailDTO = OrderDetailMapstructMapper.INSTANCE.toConfirmOrderDetailDTO(orderDetail);
            confirmOrderDTOs.add(confirmOrderDetailDTO);
        });
        Map<Integer, List<ConfirmOrderDetailDTO>> orderDetailMap = confirmOrderDTOs.stream().collect(Collectors.groupingBy(ConfirmOrderDetailDTO::getMchId));
        orders.forEach(order -> {
            ConfirmOrderDTO confirmOrderDTO = new ConfirmOrderDTO();
            confirmOrderDTO.setDetails(orderDetailMap.get(order.getMchId()));
            confirmOrderDTO.setMchId(order.getMchId());
            confirmOrderDTO.setStoreId(order.getStoreId());
            confirmOrderDTO.setTotalPrice(PriceUtil.longToBigDecimalPrice(order.getTotalPrice()));
            MchModel mchModel = mchModelMap.get(order.getMchId());
            if (Objects.nonNull(mchModel)) {
                confirmOrderDTO.setMchName(mchModel.getName());
            }
            confirmOrders.add(confirmOrderDTO);
        });
        return confirmOrders;
    }

    @Transactional
    @Override
    public OrderParentDTO submitOrder(UserPlaceOrderParams userPlaceOrderParams,boolean isDelCarts) {
        //获取商品列表
        List<ProductListModel> productModelLists = getProductListModelsByCarts(userPlaceOrderParams.getCartModels());
        log.info("开始获取购物车商品数量:{}",productModelLists.size());
        //生成母单/子单/订单子项数据
        OrderCombiner orderCombiner = getOrderCombiner(userPlaceOrderParams, productModelLists);
        log.info("开始生成订单数据:{}",orderCombiner);
        if (CollectionUtils.isEmpty(orderCombiner.getOrders())
                || CollectionUtils.isEmpty(orderCombiner.getDetails())
                || Objects.isNull(orderCombiner.getOrderParent())
        ) {
            throw new RuntimeException("创建订单失败");
        }
        OrderParent orderParent = orderCombiner.getOrderParent();
        //保存母单
        save(orderParent);
        log.info("保存母单成功:{}",orderParent.getOrderParentNo());
        //保存订单
        orderService.saveBatch(orderCombiner.getOrders(), orderCombiner.getOrders().size());
        log.info("保存订单成功:{}",orderCombiner.getOrders().size());
        //保存订单子项
        orderDetailService.saveBatch(orderCombiner.getDetails(), orderCombiner.getDetails().size());
        log.info("保存订单子项成功:{}",orderCombiner.getDetails().size());

        //保存下单记录
        orderParentMessageService.addOrderParentMessage(userPlaceOrderParams.getUser().getUser_id(),
                userPlaceOrderParams.getStoreId(),
                OrderParentMessageType.ORDER_STATUS_PLACE.getCode(),
                orderParent.getOrderParentNo(),
                OrderStatusEnum.WAIT_PAY.getCode(),
                OrderParentMessageType.ORDER_STATUS_PLACE.getName());
        log.info("保存下单记录成功");
        if(isDelCarts){
            //删除购物车
            List<Integer> cartIds = userPlaceOrderParams.getCartModels().stream().map(CartModel::getId).collect(Collectors.toList());
            delCarts(cartIds, userPlaceOrderParams.getUser().getUser_id(), userPlaceOrderParams.getUser().getStore_id());
            log.info("删除购物车成功");
        }
        OrderParentDTO dto = OrderParentMapstructMapper.INSTANCE.toDTO(orderCombiner.getOrderParent());
        return dto;
    }


    private void addFreezeRecord(Long deductionAmount, Integer storeId, String userId, String orderParentNo) {
        balanceRecordService.addFreezeRecord(deductionAmount, storeId, userId, orderParentNo, BalanceRecordTypeEnum.FREEZE_AMOUNT.getCode(), userId);
    }


    private int delCarts(List<Integer> cartIds, String userId, int storeId) {
        Example example = new Example(CartModel.class);
//        List<Integer> cartIds = userPlaceOrderParams.getCartModels().stream().map(CartModel::getId).collect(Collectors.toList());
        example.createCriteria()
                .andIn("id", cartIds)
                .andEqualTo("user_id", userId)
                .andEqualTo("store_id", storeId);
        return cartModelMapper.deleteByExample(example);
    }

    @Override
    public String placeOrder(PlaceOrderParams vo, User user) {
        try {
//            UserAddress userAddress = userAddressMapper.selectByPrimaryKey(vo.getAddressId());
            UserAddress userAddress = new UserAddress();
            userAddress.setName(vo.getName());
            userAddress.setTel(vo.getTel());
            userAddress.setAddress(vo.getAddress());
            userAddress.setSheng(vo.getSheng());
            userAddress.setCity(vo.getCity());
            userAddress.setQuyu(vo.getQuyu());
            UserPlaceOrderParams params = PlaceOrderParamsMapstructMapper.INSTANCE.toDTO(vo);
            String discount = publicMemberService.getMemberDiscountByToken(vo.getAccessId(), vo.getStoreId());
            List<CartModel> cartModels = getCartModels(vo.getCartIds());
            int payType;
            if (OrderInvoiceEnum.YES.getCode().equals(vo.getInvoice())) {
                //开票 走线下自营订单
                payType = PayTypeEnum.OFFLINE_PAY.getCode();
                params.setOrderType(OrderTypeEnum.SELF.getCode());
            } else {
                //不开票走结算通
                payType = PayTypeEnum.SETTLEMENT_PAY.getCode();
                params.setOrderType(OrderTypeEnum.POP.getCode());
            }
            Integer roleId = user.getRole_id();
            user= getUser(user.getStore_id(),user.getUser_id());
            user.setRole_id(roleId);
            params.setUser(user);
            params.setRate(new BigDecimal(discount));
            params.setExpectedDeliveryTime(vo.getExpectedDeliveryTime());
            params.setInvoice(vo.getInvoice());

            String skuNums = vo.getSkuNums();
            List<SkuNumDTO> skuNumList= getSkuNumListByString(skuNums);
            if(!CollectionUtils.isEmpty(skuNumList)){
                Map<Integer, Integer> skuNumMap = skuNumList.stream().collect(Collectors.toMap(SkuNumDTO::getSkuId, SkuNumDTO::getNum));
                for (CartModel cartModel : cartModels) {
                    Integer skuId = Integer.valueOf(cartModel.getSize_id());
                    if (skuNumMap.containsKey(skuId)) {
                        cartModel.setGoods_num(skuNumMap.get(skuId));
                    }
                }
            }
            params.setCartModels(cartModels);
            params.setUserAddress(userAddress);
            params.setStoreId(vo.getStoreId());
            params.setPayType(payType);
            params.setRemark(vo.getRemark());
            String remarks = vo.getRemarks();
            List<OrderRemarkDTO> remarkList= getRemarkList(remarks);
            params.setRemarks(remarkList);


            OrderParentServiceImpl self = SpringHelper.getBeanInfo(OrderParentServiceImpl.class);
            OrderParentDTO orderParentDTO = self.submitOrder(params,true);
            //假如订单超时处理的延时队列
            OrderCancelRunner.addOrderCancel(orderParentDTO.getOrderParentNo());
            return orderParentDTO.getOrderParentNo();
        } catch (LaiKeAPIException e) {
            log.error("下单失败 异常", e);
            throw e;
        } catch (Exception e) {
            log.error("下单失败 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ORDER_FAILED_TRY_AGAIN_LATER, "下单失败", "placeOrder");
        }
    }

    private List<SkuNumDTO> getSkuNumListByString(String skuNums) {
        if(StringUtils.isNotBlank(skuNums)){
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                return objectMapper.readValue(skuNums, new TypeReference<List<SkuNumDTO>>() {});
            } catch (Exception e) {

            }
        }
        return new ArrayList<>();
    }

    public static List<OrderRemarkDTO> getRemarkList(String remarks) {
        if(StringUtils.isNotBlank(remarks)){
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                return objectMapper.readValue(remarks, new TypeReference<List<OrderRemarkDTO>>() {});
            } catch (Exception e) {

            }

        }
        return new ArrayList<>();
    }

    public static void main(String[] args) {
        String remarks="[{\"mchId\":193,\"remark\":\"aaa\"},{\"mchId\":193,\"remark\":\"aaa\"}]";
        System.out.println(getRemarkList(remarks));
    }

    private Long getTimeSeconds(Date expireTime) {
        Date now = new Date(); // 可以设置为任意其他时间

        // 将 Date 转换为 Instant
        Instant instant1 = expireTime.toInstant();
        Instant instant2 = now.toInstant();

        // 使用 Duration 计算两个 Instant 之间的持续时间
        Duration duration = Duration.between(instant2, instant1);

        // 获取相差秒数
        long secondsBetween = duration.getSeconds();
        return secondsBetween;
    }

    //获取购物车
    private List<CartModel> getCartModels(String cartIdsStr) {
        String[] cartIdStrS = cartIdsStr.split(",");
        List<Integer> cartIds = new ArrayList<>();
        for (String cartId : cartIdStrS) {
            if (StringUtils.isNotEmpty(cartId)) {
                cartIds.add(Integer.valueOf(cartId));
            }
        }
        Example example = new Example(CartModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", cartIds);
        List<CartModel> cartModels = cartModelMapper.selectByExample(example);
        return cartModels;
    }

    //获取订单组合(母订单/子订单/订单子项)
    public OrderCombiner getOrderCombiner(UserPlaceOrderParams userPlaceOrderParams, List<ProductListModel> productModelLists) {
        OrderCombiner orderCombiner = new OrderCombiner();
        Map<String, Integer> skuNumMap = getSkuNumMap(userPlaceOrderParams.getCartModels());

        Random random = new Random();
        String timeStr = FastDateFormat.getInstance(GloabConst.TimePattern.YMDHMS2).format(new Date());

        Map<Integer, String> orderNoMap = new HashMap<>();

        Map<Integer, ProductListModel> mchProductListMap = new HashMap<>();
        for (int i = 0; i < productModelLists.size(); i++) {
            ProductListModel productModel = productModelLists.get(i);
            if (productModel.getMch_id() != null) {
                mchProductListMap.put(productModel.getId(), productModel);
            }
            if (productModel.getMch_id() != null && !orderNoMap.containsKey(productModel.getMch_id())) {
                orderNoMap.put(productModel.getMch_id(), "");
            }
        }
        List<String> orderNoList = orderParentNoSeq.getOrderNoList(orderNoMap.size());
        int i=0;
        for (Integer mchId : orderNoMap.keySet()){
            orderNoMap.put(mchId, orderNoList.get(i));
            i++;
        }
        log.info("生成子单号:{}",orderNoMap);

        //获取sku的map
        Map<Integer, List<ConfiGureModel>> mchSkuListMap = getMchSkuListMap(userPlaceOrderParams, mchProductListMap);

        Map<Integer ,MchModel> mchModelMap = getMchModelMap(productModelLists);

        Map<Integer, BrandClassModel> brandClassModelMap = getBrandClassModel(productModelLists);

        //用户信息
        User user = userPlaceOrderParams.getUser();
        //地址信息
        UserAddress userAddress = userPlaceOrderParams.getUserAddress();


        String orderParentNo = createOrderParentNo();
        log.info("生成母单号:{}",orderParentNo);

        //获取子订单
        List<Order> orders = new ArrayList<>();
        //订单详情
        List<OrderDetail> orderDetailList = new ArrayList<>(userPlaceOrderParams.getCartModels().size());

        Date now = new Date();
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DAY_OF_MONTH, 7);
        Date expireTime = instance.getTime();

        for (List<ConfiGureModel> mchSkuList : mchSkuListMap.values()) {
            if (CollectionUtils.isEmpty(mchSkuList)) {
                continue;
            }

            ProductListModel product = mchProductListMap.get(mchSkuList.get(0).getPid());
            if (Objects.isNull(product)) {
                continue;
            }
            Integer mchId =product.getMch_id();
            //创建订单
            Order order = createOrder(userPlaceOrderParams, mchSkuList, mchProductListMap, user, userAddress, orderParentNo, orderNoMap, timeStr, random, now, productModelLists, skuNumMap, orderDetailList, expireTime,mchModelMap,brandClassModelMap,mchId);
            orders.add(order);
        }
        log.info("生成订单列表成功");
        OrderParent orderParent = createOrderParent(userPlaceOrderParams, orderParentNo, now, user, userAddress, orders, expireTime, productModelLists,orderDetailList);
        log.info("生成母订单成功");
        orderCombiner.setOrderParent(orderParent);
        orderCombiner.setOrders(orders);
        orderCombiner.setDetails(orderDetailList);
        return orderCombiner;
    }

    private Map<Integer, BrandClassModel> getBrandClassModel(List<ProductListModel> productModelLists) {
        List<Integer> brandIds = new ArrayList<>(productModelLists.size());
        productModelLists.forEach(item->{
            brandIds.add(item.getBrand_id());
        });
        if(CollectionUtils.isEmpty(brandIds)){
            return new HashMap<>();
        }
        Example example = new Example(BrandClassModel.class);
        example.createCriteria()
                .andIn("brand_id", brandIds);
        List<BrandClassModel> brandClassModels = brandClassModelMapper.selectByExample(example);
        return brandClassModels.stream().collect(Collectors.toMap(BrandClassModel::getBrand_id,s->s));
    }

    /**
     * @param userPlaceOrderParams 下单参数
     * @param orderParentNo        母单号
     * @param now                  当前时间
     * @param user                 用户
     * @param userAddress          用户地址
     * @param orders               子订单列表
     * @param expireTIme           过期时间
     * @return
     */
    private OrderParent createOrderParent(UserPlaceOrderParams userPlaceOrderParams, String orderParentNo, Date now, User user, UserAddress userAddress, List<Order> orders, Date expireTIme, List<ProductListModel> productModelLists,List<OrderDetail> details) {
        OrderParent orderParent = new OrderParent();
        orderParent.setOrderType(userPlaceOrderParams.getOrderType());
        orderParent.setOrderParentNo(orderParentNo);
        orderParent.setStoreId(userPlaceOrderParams.getStoreId());
        orderParent.setStatus(OrderParentStatusEnum.WAIT_PAY.getCode());
        orderParent.setCreateTime(now);
        orderParent.setUserId(user.getUser_id());
        orderParent.setOperationType(userPlaceOrderParams.getOperationType());
        orderParent.setProdcutNum(productModelLists.size());
        orderParent.setOrderNum(orders.size());
//        orderParent.setUserName(user.getUser_name());
        orderParent.setUserName(user.getSignatory_name());
        orderParent.setUserTel(user.getMobile());
        if (Objects.nonNull(userAddress)) {
            orderParent.setProvice(userAddress.getSheng());
            orderParent.setCity(userAddress.getCity());
            orderParent.setArea(userAddress.getQuyu());
            orderParent.setAddress(userAddress.getAddress());
            orderParent.setMobile(userAddress.getTel());
            orderParent.setName(userAddress.getName());
        }
        long totalCostPrice = 0L;

        long oldTotalPrice = 0L;
        long totalPrice = 0L;
        int totalNum = 0;
        int skuNum=0;
        BigDecimal totalVolume = BigDecimal.ZERO;
        for (Order order : orders) {
            totalCostPrice += order.getTotalCostPrice();
            totalVolume = totalVolume.add(order.getTotalVolume());
            oldTotalPrice += order.getOldTotalPrice();
            totalNum += order.getNum();
            skuNum+=order.getSkuNum();
            totalPrice+=order.getTotalPrice();
        }
        orderParent.setSkuNum(skuNum);
        orderParent.setNum(totalNum);
        orderParent.setRemark(userPlaceOrderParams.getRemark());
        orderParent.setTotalCostPrice(totalCostPrice);

//        Long rateLongPrice = PriceUtil.getRateLongPrice(userPlaceOrderParams.getRate());
//        long totalPrice = PriceUtil.longRateToLong(oldTotalPrice ,rateLongPrice);
        //将总销售价 * 折扣 改成 子单折扣价总和
        orderParent.setTotalPrice(totalPrice);
        orderParent.setOriginalTotalPrice(totalPrice);
        orderParent.setOldTotalPrice(oldTotalPrice);
        orderParent.setOriginalOldTotalPrice(oldTotalPrice);
        orderParent.setTotalVolume(totalVolume);
        long taxation = 0L;
        if (OrderInvoiceEnum.YES.getCode().equals(userPlaceOrderParams.getInvoice())) {
//            taxation = taxRate * totalPrice / 100L;
            taxation = PriceUtil.calcTaxRate( totalPrice);
        }
        orderParent.setTaxation(taxation);
        orderParent.setOriginalTaxation(taxation);

        orderParent.setPayPrice(orderParent.getTotalPrice() + orderParent.getTaxation());
        orderParent.setOriginalPayPrice(orderParent.getTotalPrice() + orderParent.getTaxation());

        orderParent.setDeleted(DelFlagEnum.NORMAL.getCode());
        orderParent.setDiscount(userPlaceOrderParams.getRate());
        orderParent.setInvoice(userPlaceOrderParams.getInvoice());
        if (Objects.nonNull(userPlaceOrderParams.getPayType())) {
            orderParent.setPayType(userPlaceOrderParams.getPayType());
        }
        orderParent.setStatus(OrderParentStatusEnum.WAIT_PAY.getCode());
        if (Objects.nonNull(userPlaceOrderParams.getExpectedDeliveryTime())) {
            //期望发货日期
            orderParent.setExpectedDeliveryTime(userPlaceOrderParams.getExpectedDeliveryTime());
        }
        orderParent.setExpireTime(expireTIme);
        orderParent.setCreateBy(user.getUser_id());
        orderParent.setCreateTime(now);
        orderParent.setUpdateBy(user.getUser_id());
        orderParent.setUpdateTime(now);
        orderParent.setOrderType(userPlaceOrderParams.getOrderType());
        //结算金额等于总采购金额
        orderParent.setSettlementAmount(orderParent.getTotalCostPrice());
        orderParent.setSettlementStatus(SettlementStatusEnum.NO.getCode());
        orderParent.setKeyWords(createKeyWords(orderParentNo,details,orderParent));
        if(Objects.nonNull(user.getRole_id())){
            orderParent.setRoleId(user.getRole_id());
            RoleModel roleModel = roleMapper.selectByPrimaryKey(user.getRole_id());
            Optional.of(roleModel).ifPresent(role -> {
                orderParent.setRoleName(role.getName());
            });
        }
        return orderParent;
    }

    private String createKeyWords(String orderParentNo, List<OrderDetail> details,OrderParent orderParent) {
        StringBuilder sb = new StringBuilder();
        sb.append(orderParentNo);
        if(StringUtils.isNotBlank(orderParent.getName())){
            sb.append(SplitUtils.DH);
            sb.append(orderParent.getName());
        }
        if(StringUtils.isNotBlank(orderParent.getMobile())){
            sb.append(SplitUtils.DH);
            sb.append(orderParent.getMobile());
        }
        if(StringUtils.isNotBlank(orderParent.getUserName())){
            sb.append(SplitUtils.DH);
            sb.append(orderParent.getUserName());
        }
        details.forEach(detail -> {
            if(StringUtils.isNotBlank(detail.getProductCode())){
                sb.append(SplitUtils.DH);
                sb.append(detail.getProductCode());
            }
        });
        return sb.toString();
    }

    private Map<Integer, String> getOrderRemarkMap(List<OrderRemarkDTO> remarks) {
        if (CollectionUtils.isEmpty(remarks)) {
            return new HashMap<Integer, String>();
        }
        return remarks.stream().collect(Collectors.toMap(OrderRemarkDTO::getMchId, OrderRemarkDTO::getRemark));
    }

    private Order createOrder(UserPlaceOrderParams userPlaceOrderParams, List<ConfiGureModel> mchSkuList, Map<Integer, ProductListModel> productMap, User user, UserAddress userAddress, String orderParentNo, Map<Integer, String> orderNoMap, String timeStr, Random random, Date now, List<ProductListModel> productModelLists, Map<String, Integer> skuNumMap, List<OrderDetail> orderDetailList, Date expireTime,Map<Integer ,MchModel> mchModelMap, Map<Integer, BrandClassModel> brandClassModelMap ,Integer mchId) {
        Map<Integer, String> orderRemarkMap = getOrderRemarkMap(userPlaceOrderParams.getRemarks());
        Order order = new Order();
        order.setCustomerId(user.getCustomer_id());
        order.setDeleted(DelFlagEnum.NORMAL.getCode());

        order.setMchId(mchId);
        MchModel mchModel = mchModelMap.get(mchId);
        if(Objects.nonNull(mchModel) && StringUtils.isNotBlank(mchModel.getName())){
            order.setMchName(mchModel.getName());
        }
        order.setOrderType(userPlaceOrderParams.getOrderType());
        order.setUserId(user.getUser_id());
        if (Objects.nonNull(userAddress)) {
            order.setProvice(userAddress.getSheng());
            order.setCity(userAddress.getCity());
            order.setArea(userAddress.getQuyu());
            order.setMobile(userAddress.getTel());
            order.setName(userAddress.getName());
            order.setAddress(userAddress.getAddress());
        }
        order.setOrderType(userPlaceOrderParams.getOrderType());
        order.setOrderParentNo(orderParentNo);
        String orderNo = orderNoMap.get(mchId);
        if (StringUtils.isBlank(orderNo)) {
            orderNo = orderParentNoSeq.getOrderNo();
        }
        order.setOrderNo(orderNo);
        order.setStoreId(userPlaceOrderParams.getStoreId());
        order.setCreateBy(user.getUser_id());
        order.setCreateTime(now);
        order.setUpdateBy(user.getUser_id());
        order.setUpdateTime(now);

        order.setOperationType(userPlaceOrderParams.getOperationType());
        order.setDiscount(userPlaceOrderParams.getRate());
        order.setNum(productModelLists.size());
        String remark = "";
        if (orderRemarkMap.containsKey(order.getMchId())) {
            remark = orderRemarkMap.get(order.getMchId());
        }
        order.setRemark(remark);
        order.setExpireTime(expireTime);
        order.setOrderType(userPlaceOrderParams.getOrderType());
        if (Objects.nonNull(userPlaceOrderParams.getPayType())) {
            order.setPayType(userPlaceOrderParams.getPayType());
        }
        order.setStatus(OrderStatusEnum.WAIT_PAY.getCode());


        long oldTotalPrice = 0L;
        long totalPrice = 0L;
        BigDecimal totalVolume = BigDecimal.ZERO;//体积
        long totalCostPriice = 0L;
        int numTotal = 0;
        int bomNum = 0;
        int detailNumber=0;
        Set<String> brandSet = new HashSet<>(mchSkuList.size());
        for (ConfiGureModel sku : mchSkuList) {
            detailNumber++;
            long oldPrice = getPrice(sku.getPrice());
            Long rateLongPrice = PriceUtil.getRateLongPrice(userPlaceOrderParams.getRate());
            long price = PriceUtil.longRateToLong(rateLongPrice , oldPrice );
            long costPrice = getPrice(sku.getCostprice());
            int num = 1;
            if (skuNumMap.containsKey(sku.getId().toString())) {
                num = skuNumMap.get(sku.getId().toString());
            }
            numTotal += num;
            oldTotalPrice += oldPrice * num;
            totalCostPriice += costPrice * num;
            totalPrice += price * num;
            if (Objects.nonNull(sku.getCapacity())) {
                totalVolume = totalVolume.add(sku.getCapacity().multiply(new BigDecimal(num)));
            }
            if (Objects.nonNull(sku.getBom_nums())) {
                bomNum += sku.getBom_nums() * num;
            }
            String skuImg = publiceService.getImgPath(sku.getImg(), userPlaceOrderParams.getStoreId());
            ProductListModel product = productMap.get(sku.getPid());
            String productImg = publiceService.getImgPath(product.getCover_map(), userPlaceOrderParams.getStoreId());
            //创建订单子项
            OrderDetail detail = createOrderDetail(userPlaceOrderParams, sku, orderParentNo, orderNo, product, num, user, costPrice, oldPrice, price, now,  brandClassModelMap,detailNumber,skuImg,productImg);
            orderDetailList.add(detail);

            brandSet.add(detail.getBrandName());
        }
        String brandStr = String.join(",", brandSet);
        order.setBrands(brandStr);
        order.setTotalBomNum(bomNum);
        order.setSkuNum(mchSkuList.size());
        long taxation = 0L;
        order.setProductNum(getProductNumBySkuList(mchSkuList));

        order.setTotalPrice(totalPrice);
        order.setOriginalTotalPrice(totalPrice);
        order.setOldTotalPrice(oldTotalPrice);
        order.setOriginalOldTotalPrice(oldTotalPrice);
        long payPrice = totalPrice;
//        long payPrice = PriceUtil.longRateToLong(totalPrice , PriceUtil.getRateLongPrice(userPlaceOrderParams.getRate()));
        if (OrderInvoiceEnum.YES.getCode().equals(userPlaceOrderParams.getInvoice())) {
//            taxation = payPrice * taxRate / 100L;
            taxation = PriceUtil.calcTaxRate(payPrice);
            payPrice += taxation;
        }
        order.setPayPrice(payPrice);
        order.setOriginalPayPrice(payPrice);
        order.setTaxation(taxation);
        order.setOriginalTaxation(taxation);
        order.setTotalVolume(totalVolume);
        order.setTotalCostPrice(totalCostPriice);
        order.setSettlementStatus(SettlementStatusEnum.NO.getCode());
        order.setNum(numTotal);
        order.setSettlementAmount(totalCostPriice);

        order.setExpectedTime(expireTime);
        order.setExpectedDeliveryTime(userPlaceOrderParams.getExpectedDeliveryTime());
        order.setDiscount(userPlaceOrderParams.getRate());
        order.setKeyWords(createOrderKeyWords(orderNo, mchSkuList,order));

        return order;
    }

    private String createOrderKeyWords(String orderNo, List<ConfiGureModel> mchSkuList,Order order) {
        StringBuilder sb = new StringBuilder();
        sb.append(orderNo);
        sb.append(SplitUtils.DH);
        sb.append(order.getMobile());
        sb.append(SplitUtils.DH);
        sb.append(order.getName());
        if(StringUtils.isNotBlank(order.getMchName())){
            sb.append(SplitUtils.DH);
            sb.append(order.getMchName());
        }
        mchSkuList.forEach(sku->{
            sb.append(SplitUtils.DH);
            sb.append(sku.getProduct_code());
        });
        return sb.toString();
    }

    private Integer getProductNumBySkuList(List<ConfiGureModel> mchSkuList) {
        Map<Integer, List<ConfiGureModel>> collect = mchSkuList.stream().collect(Collectors.groupingBy(ConfiGureModel::getPid));
        return collect.size();
    }

    private static @NotNull OrderDetail createOrderDetail(UserPlaceOrderParams userPlaceOrderParams, ConfiGureModel sku, String orderParentNo, String orderNo, ProductListModel product, int num, User user, long costPrice, long oldPrice, long price, Date now, Map<Integer, BrandClassModel> brandClassModelMap,int detailNumber ,String skuImg,String productImg) {
        OrderDetail detail = new OrderDetail();
        detail.setDetailNo(orderNo+getThreeLengthStr(detailNumber));
        detail.setOrderParentNo(orderParentNo);
        detail.setOrderNo(orderNo);
        detail.setProductId(product.getId());
        detail.setDeleted(DelFlagEnum.NORMAL.getCode());
        detail.setMchId(product.getMch_id());
        detail.setNum(num);
        detail.setProductName(product.getProduct_title());
        detail.setBomNum(sku.getBom_nums());
        detail.setUserId(user.getUser_id());
        detail.setCostPrice(costPrice * num);
        detail.setProductPrice(oldPrice * num);
        detail.setTotalSupplierPrice(price * num);
        detail.setOriginalTotalSupplierPrice(price * num);
        detail.setSupplierPrice(price);
        detail.setOriginalSupplierPrice(price);
        detail.setBagType(sku.getBag_type());
        detail.setProductCode(sku.getProduct_code());
        detail.setMarque(sku.getMarque());
        detail.setSkuId(sku.getId().toString());
        detail.setUnit(sku.getUnit());
        detail.setStoreId(userPlaceOrderParams.getStoreId());
        int bomNum = 0;
        if (Objects.nonNull(sku.getBom_nums())) {
            bomNum = sku.getBom_nums() * num;
        }
        detail.setBomNum(bomNum);
        BigDecimal volume = BigDecimal.ZERO;
        if (Objects.nonNull(sku.getCapacity())) {
            volume = sku.getCapacity().multiply(new BigDecimal(num));
        }
        detail.setVolume(Objects.nonNull(sku.getCapacity()) ? sku.getCapacity() : BigDecimal.ZERO);
        detail.setTotalVolume(volume);
        long detailTaxation = 0L;
        if (OrderInvoiceEnum.YES.getCode().equals(userPlaceOrderParams.getInvoice())) {
//            detailTaxation = detail.getTotalSupplierPrice() * taxRate / 100L;
            detailTaxation = PriceUtil.calcTaxRate(detail.getTotalSupplierPrice());
        }

        detail.setCreateTime(now);
        detail.setCreateBy(user.getUser_id());
        detail.setTaxation(detailTaxation);
        detail.setPayPrice(detailTaxation + detail.getTotalSupplierPrice());
        detail.setOriginalPayPrice(detailTaxation + detail.getTotalSupplierPrice());
        detail.setUpdateBy(user.getUser_id());
        detail.setUpdateTime(now);
        //结算金额等于采购价总金额
        detail.setSettlementPrice(costPrice);
        detail.setTotalSettlementPrice(costPrice * num);
        detail.setProductCode(sku.getProduct_code());
        detail.setAttribute(sku.getAttribute());
        detail.setImg(skuImg);
        detail.setImgArr(sku.getImg_arr());
        detail.setImgurl(skuImg);
        detail.setSubtitle(product.getSubtitle());
        BrandClassModel brandClassModel = brandClassModelMap.get(product.getBrand_id());
        if(Objects.nonNull(brandClassModel)){
            detail.setBrandId(brandClassModel.getBrand_id());
            detail.setBrandName(brandClassModel.getBrand_name());
        }
        if(StringUtils.isNotBlank(product.getMaterial())){
            detail.setMaterial(product.getMaterial());
        }
        return detail;
    }

    private String createOrderParentNo() {
        OrderParentNoSeq orderParentNoSeq = SpringHelper.getBeanInfo(OrderParentNoSeq.class);
        return orderParentNoSeq.getOrderParentNo();
//        Random random = new Random();
//        int i = random.nextInt(9999998);
//        String iStr = getSevenLengthStr(i);
//        return FastDateFormat.getInstance(GloabConst.TimePattern.YMD1).format(new Date()) + iStr;
//        return FastDateFormat.getInstance(GloabConst.TimePattern.YMDHMS1).format(new Date()) + iStr;
    }


    private static @NotNull String getThreeLengthStr(int i) {
        String iStr = String.valueOf(i);
        while (iStr.length() < 3) {
            iStr = "0" + iStr;
        }
        return iStr;
    }

    private static @NotNull String getSevenLengthStr(int i) {
        String iStr = String.valueOf(i);
        while (iStr.length() < 7) {
            iStr = "0" + iStr;
        }
        return iStr;
    }


    public Map<String, Integer> getSkuNumMap(List<CartModel> cartModels) {
        if (!CollectionUtils.isEmpty(cartModels)) {
            return cartModels.stream().collect(Collectors.groupingBy(CartModel::getSize_id, Collectors.summingInt(CartModel::getGoods_num)));
        }
        return new HashMap<>();
    }

    public long getPrice(BigDecimal price) {

        return PriceUtil.bigDecimalToLongPrice(price);
    }

    private Map<Integer, List<ConfiGureModel>> getMchSkuListMap(UserPlaceOrderParams userPlaceOrderParams, Map<Integer, ProductListModel> mchProductListMap) {
        List<ConfiGureModel> skuList = getSkuList(userPlaceOrderParams.getCartModels());
        Map<Integer, List<ConfiGureModel>> mchSkuListMap = new HashMap<>(skuList.size());
        for (ConfiGureModel sku : skuList) {
            ProductListModel productListModel = mchProductListMap.get(sku.getPid());
            if (Objects.isNull(productListModel)) {
                continue;
            }
            List<ConfiGureModel> mchSkuList = mchSkuListMap.get(productListModel.getMch_id());
            if (CollectionUtils.isEmpty(mchSkuList)) {
                mchSkuList = new ArrayList<>();
            }
            mchSkuList.add(sku);
            mchSkuListMap.put(productListModel.getMch_id(), mchSkuList);
        }
        return mchSkuListMap;
    }

    private List<ConfiGureModel> getSkuList(List<CartModel> cartModels) {
        List<String> skuIds = cartModels.stream().map(CartModel::getSize_id).collect(Collectors.toList());

        Example example = new Example(ConfiGureModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", skuIds);
        return configureModelMapper.selectByExample(example);
    }



    public @NotNull Map<Integer, MchModel> getMchModelMap(List<ProductListModel> productModelList) {
        List<Integer> mchIds = productModelList.stream().map(ProductListModel::getMch_id).collect(Collectors.toList());
        Example example = new Example(MchModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", mchIds);
        List<MchModel> mchModels = mchModelMapper.selectByExample(example);
        return mchModels.stream().collect(Collectors.toMap(MchModel::getId, s -> s));
    }

    private List<ProductListModel> getProductListModelsByCarts(List<CartModel> cartModels) {
        List<Integer> productIdList = cartModels.stream().map(CartModel::getGoods_id).collect(Collectors.toList());

        Example example = new Example(ProductListModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", productIdList);
        return productListModelMapper.selectByExample(example);
    }

    private List<OrderProductsDTO> getOrderProductsByOrderParentNo(String orderParentNo){
        List<OrderDetail> details = orderDetailService.findByOrderParentNo(orderParentNo);
        List<OrderProductsDTO> products = new ArrayList<>();
        details.forEach(d ->{
            OrderProductsDTO orderProductsDTO = new OrderProductsDTO();
            orderProductsDTO.setProductName(d.getProductName());
            orderProductsDTO.setImgUrl(d.getImgurl());
            orderProductsDTO.setNum(d.getNum());
            products.add(orderProductsDTO);
        });
        return products;
    }


}




